﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;

namespace myCommon.Image
{
    public static class ImageProcess
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public static Bitmap JoinImage(List<Bitmap> imageList, List<RectangleF> positionList, int imgWidth, int imgHeight)
        {
            //图片列表
            if (imageList.Count <= 0)
                return null;
            Bitmap tableChartImage = new Bitmap(imgWidth, imgHeight);
            Graphics graph = Graphics.FromImage(tableChartImage);
            //初始化这个大图
            graph.DrawImage(tableChartImage, imgWidth, imgHeight);
            //初始化当前宽
            //int currentWidth = 0;
            //foreach (Image i in imageList)
            //{
            //    //拼图
            //    graph.DrawImage(i, currentWidth, 0);
            //    //拼接改图后，当前宽度
            //    currentWidth += i.Width;
            //}
            for (int i = 0; i < imageList.Count; i++)
            {
                graph.DrawImage(
                    imageList[i],
                    positionList[i].X,
                    positionList[i].Y,
                    positionList[i].Width,
                    positionList[i].Height
                    );
            }
            return tableChartImage;


        }
        //————————————————
        //原文链接：出处：http://blog.csdn.net/tigertianx/article/details/7098490
        //public static Bitmap Bytes2Bimap(byte[] b)
        //{
        //    byte[] bytelist = b;
        //    Bitmap bm = null;
            
        //    if (b.Length > 0)
        //    {
        //        MemoryStream ms1 = new MemoryStream(bytelist);
                
        //        bm =System.Drawing.Image.FromStream(ms1);
        //    }
        //    return bm;
        //}

        // 
        /// <summary>
        /// 将数组转换成彩色图片, 来源：【https://www.cnblogs.com/tlduck/p/6146267.html】
        /// </summary>
        /// <param name="rawValues">图像的byte数组</param>
        /// <param name="width">图像的宽</param>
        /// <param name="height">图像的高</param>
        /// <returns>Bitmap对象</returns>
        public static Bitmap ToColorBitmap(byte[] rawValues, int width, int height ,PixelFormat pixelFormat= PixelFormat.Format32bppArgb)
        {
            //// 申请目标位图的变量，并将其内存区域锁定
            try
            {
                Bitmap m_currBitmap = new Bitmap(width, height, pixelFormat);
                //m_currBitmap.SetResolution(196, 196);
                Rectangle m_rect = new Rectangle(0, 0, width, height);
                var m_bitmapData = m_currBitmap.LockBits(m_rect, ImageLockMode.WriteOnly, pixelFormat);
                IntPtr iptr = m_bitmapData.Scan0;  // 获取bmpData的内存起始位置  
                //// 用Marshal的Copy方法，将刚才得到的内存字节数组复制到BitmapData中  
                System.Runtime.InteropServices.Marshal.Copy(rawValues, 0, iptr, width * height * 4);
                m_currBitmap.UnlockBits(m_bitmapData);
                return m_currBitmap;
            }
            catch (System.Exception ex)
            {
                log.Error("", ex);
                return null;
            }
        }

        public static BitmapSource CreateBitmapSource(int width=1, int height=1,byte b=0xff, byte g=0xff, byte r=0xff)
        {
            // Define parameters used to create the BitmapSource.
            System.Windows.Media.PixelFormat pf = System.Windows.Media.PixelFormats.Bgr32;
            int rawStride = (width * pf.BitsPerPixel + 7) / 8;
            byte[] rawImage = new byte[rawStride * height];
            if (width == 1 && height == 1)
            {
                rawImage[0] =r;
                rawImage[1] = g;
                rawImage[2] = b;
            }
            else
            {
                // Initialize the image with data.
                Random value = new Random();
                value.NextBytes(rawImage);
            }

            // Create a BitmapSource.
            BitmapSource bitmap = BitmapSource.Create(width, height,
                96, 96, pf, null,
                rawImage, rawStride);
            
            // Create an image element;
            // Set image source.
            return bitmap;
        }

        public static BitmapSource ConvertToBitmapSource(int width, int  height,System.Windows.Media.PixelFormat pf,Array data, int CONST_DPI = 96)
        {
            int rawStride = (width * pf.BitsPerPixel + 7) / 8;

            BitmapSource bitmap = BitmapSource.Create(width, height,
                    CONST_DPI, CONST_DPI, pf, null,
                    data, rawStride);

            return bitmap;
        }

        /// <summary>
        /// Create a PixelFormat and find the value of its properties
        /// https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.pixelformat?view=net-5.0
        /// 
        /// </summary>
        /// <returns></returns>
        public static System.Windows.Media.PixelFormat createPixelFormat()
        {
            // Create a PixelFormat object.
            System.Windows.Media.PixelFormat myPixelFormat = new System.Windows.Media.PixelFormat();

            // Make this PixelFormat a Gray32Float pixel format.
            myPixelFormat = System.Windows.Media.PixelFormats.Gray32Float;

            // Get the number of bits-per-pixel for this format. Because
            // the format is "Gray32Float", the float value returned will be 32.
            int bpp = myPixelFormat.BitsPerPixel;

            // Get the collection of masks associated with this format.
            IList<System.Windows.Media.PixelFormatChannelMask> myChannelMaskCollection = myPixelFormat.Masks;

            // Capture the mask info in a string.
            String stringOfValues = " ";
            foreach (System.Windows.Media.PixelFormatChannelMask myMask in myChannelMaskCollection)
            {
                IList<byte> myBytesCollection = myMask.Mask;
                foreach (byte myByte in myBytesCollection)
                {
                    stringOfValues = stringOfValues + myByte.ToString();
                }
            }

            // Return the PixelFormat which, for example, could be 
            // used to set the pixel format of a bitmap by using it to set
            // the DestinationFormat of a FormatConvertedBitmap.
            return myPixelFormat;
        }


        [DllImport("gdi32")]
        static extern int DeleteObject(IntPtr o);

        /// <summary>
        /// 将Bitmap转成BitmapSource
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static BitmapSource BitmapToBitmapSource(System.Drawing.Bitmap source)
        {
            BitmapSource bs = null;
            IntPtr ip = new IntPtr();
            try
            {
                ip = source.GetHbitmap();
                bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                         ip, IntPtr.Zero, Int32Rect.Empty,
                         System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
                bs.Freeze();
            }
            catch(Exception ex)
            {
                log.Error("", ex);
            }
            finally
            {
                DeleteObject(ip);
            }

            return bs;
        }

        public static Bitmap ImageResize(Bitmap bitmapFull, float dstWidth, float dstHeight)
        {
            return ImageResize(bitmapFull, Convert.ToInt32(dstWidth), Convert.ToInt32(dstHeight));
        }
        public static Bitmap ImageResize(Bitmap bitmapFull,int dstWidth, int dstHeight)
        {
            //Bitmap bitmapFull = new Bitmap((Int32)(rc.Width / scale), (Int32)(rc.Height / scale));
            Bitmap bitmapSmall = new Bitmap(dstWidth, dstHeight);

            Graphics g_Full = Graphics.FromImage(bitmapFull);
            Graphics g_small = Graphics.FromImage(bitmapSmall); 
            
            g_small.InterpolationMode = InterpolationMode.Low; 
            g_small.DrawImage(bitmapFull, 
                new Rectangle(0, 0, dstWidth, dstHeight), 
                new Rectangle(0, 0, bitmapFull.Width, bitmapFull.Height), 
                GraphicsUnit.Pixel);
            g_small.Dispose(); 
            g_Full.Dispose();

            return bitmapSmall;
        }

        ///<summary> 
        /// 生成缩略图 
        /// </summary> 
        /// <param name="originalImagePath">源图路径（物理路径）</param> 
        /// <param name="thumbnailPath">缩略图路径（物理路径）</param> 
        /// <param name="width">缩略图宽度</param> 
        /// <param name="height">缩略图高度</param> 
        /// <param name="mode">生成缩略图的方式</param>     
        //public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode out string outthumbnailPath)
        //{
        //    System.Drawing.Image originalImage = System.Drawing.Image.FromFile(originalImagePath);

        //    int towidth = width;
        //    int toheight = height;

        //    int x = 0;
        //    int y = 0;
        //    int ow = originalImage.Width;
        //    int oh = originalImage.Height;

        //    switch (mode)
        //    {
        //        case "HW"://指定高宽缩放（可能变形）                 
        //            break;
        //        case "W"://指定宽，高按比例                     
        //            toheight = originalImage.Height * width / originalImage.Width;
        //            break;
        //        case "H"://指定高，宽按比例 
        //            towidth = originalImage.Width * height / originalImage.Height;
        //            break;
        //        case "Cut"://指定高宽裁减（不变形）                 
        //            if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
        //            {
        //                oh = originalImage.Height;
        //                ow = originalImage.Height * towidth / toheight;
        //                y = 0;
        //                x = (originalImage.Width - ow) / 2;
        //            }
        //            else
        //            {
        //                ow = originalImage.Width;
        //                oh = originalImage.Width * height / towidth;
        //                x = 0;
        //                y = (originalImage.Height - oh) / 2;
        //            }
        //            break;
        //        default:
        //            break;
        //    }

        //    //新建一个bmp图片 
        //    System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);

        //    //新建一个画板 
        //    Graphics g = System.Drawing.Graphics.FromImage(bitmap);

        //    //设置高质量插值法 
        //    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

        //    //设置高质量,低速度呈现平滑程度 
        //    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

        //    //清空画布并以透明背景色填充 
        //    g.Clear(Color.Transparent);

        //    //在指定位置并且按指定大小绘制原图片的指定部分 
        //    g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
        //     new Rectangle(x, y, ow, oh),
        //     GraphicsUnit.Pixel);

        //    try
        //    {
        //        //以jpg格式保存缩略图 
        //        bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg);
        //        outthumbnailPath = thumbnailPath;
        //    }
        //    catch (System.Exception e)
        //    {
        //        throw e;
        //    }
        //    finally
        //    {
        //        originalImage.Dispose();
        //        bitmap.Dispose();
        //        g.Dispose();
        //    }
        //}
    }
}
